#ifndef THREADWINDOW_H
#define THREADWINDOW_H

#include <QWidget>
#include <QThread>
#include <QDebug>
#include <QTest>
#include <QFile>
#include <QStandardItemModel>
#include <QRunnable>
#include <QThreadPool>
/*
 * 1、设计派生类继承自 public QObject QRunnable
 * 2、重写run 方法 实现逻辑任务
 * 3、主线程实例化线程池对象
 * 4、启动线程池
 */
class WorkerPhool : public QObject, public QRunnable{
    Q_OBJECT
public:
    WorkerPhool(QObject* p=nullptr):QObject(p){}
    void run() override{
        for(int i=0;i<=10;i++)
        {
            QTest::qSleep(1000);
            qDebug()<<"WorkerPhool"<<i;
//            emit sendVal(i);//是一个任务执行中用来发送中间或最终结果的信号
        }
    }
};

/*核心区别：	
线程模型和控制方式：
ObjectWorkerThread：
属于 基于 QObject 的多线程任务分发模型。
任务执行逻辑 (doWork1) 是通过 槽函数 调用，依赖信号与槽的触发机制。
将任务逻辑对象（QObject）分离到目标线程（QThread）中运行，使用 事件驱动 的方式处理多线程任务。
适合 需要定期触发、交互性强、可扩展 的任务。
WorkThread：
属于 直接继承 QThread 的线程执行模型。
通过重载 run 方法，将任务逻辑写入 run 函数内，线程启动时自动调用。
使用的是传统的 线程函数 模式，任务逻辑与线程绑定在一起。
适合 一次性任务 或 线性耗时任务，如文件处理、数据解析等。


应用场景对比：
ObjectWorkerThread 的场景：
需要运行在独立线程中的长期任务。
任务需要被动态触发，例如响应按钮事件。
任务与线程解耦，希望实现灵活的任务管理。
比如：后台计算、长时间数据采集。
WorkThread 的场景：
执行一个确定性任务，例如文件读取或数据解析。
任务逻辑相对简单，不需要动态调整。
比如：解析文件内容，将结果逐行发送给主线程显示。
*/













/*
 * 1、设计派生类 继承自QObject
 * 2、自定义槽函数完成逻辑任务
 * 3、主线程中定义任务类对象，不能指定父对象
 * 4、实例化线程对象QThread
 * 5、调用moveToThread 使用指定线程处理任务
 * 6、启动线程
 * 7、启动线程后不会调用任务函数，需要connect绑定doWork
 * 8、释放资源
 */
class ObjectWorkerThread  : public QObject{
    Q_OBJECT
public:
    ObjectWorkerThread(QObject* p=nullptr):QObject(p){}
public slots:
    void doWork1()
    {
        for(int i=0;i<=10;i++)
        {
            QTest::qSleep(1000);
            emit sendVal(i);
        }
    }
signals:
    void sendVal(int val);////是一个任务执行中用来发送中间或最终结果的信号
};


/*
 * 1、QThread 派生子类  WorkThread
 * 2、重写run()  方法
 * 3、实例化WorkThread 对象
 * 4、绑定信号槽
 * 5、启动子线程
 * 6、资源回收
 */

class WorkThread : public QThread
{
    Q_OBJECT
public:
    WorkThread(QObject* p):QThread(p){}
protected:
    void run() override{
        QFile file("../empty/stu.dat");
        file.open(QIODevice::ReadOnly);
        QTextStream in(&file);
        QString line;
        QFileInfo info(file);
        int curSize = 0;
        int totalSize = info.size();
        sendTotalSize(totalSize);
        while(!in.atEnd())
        {
            sl.clear();
            in>>line;
            sl = line.split(',');
            curSize += line.size();

            emit sendLine(sl,curSize);
            curSize += 2;

//            emit sendVal(i);
//            emit sendLine(sl);
        }
    }
    QStringList sl;
signals:
    void sendTotalSize(int num);
    void sendLine(QStringList sl,int lineSize);
};

namespace Ui {
class ThreadWindow;
}

class ThreadWindow : public QWidget
{
    Q_OBJECT

public:
    explicit ThreadWindow(QWidget *parent = 0);
    ~ThreadWindow();

private slots:
    void on_startButton_clicked();
    void recTotalSize(int val);
    void recData(QStringList sl,int lineSize);
private:
    Ui::ThreadWindow *ui;
    WorkThread * work;
    QStandardItemModel *sModel;
    ObjectWorkerThread* objWorker;
    QThread * wThread;
    WorkerPhool * wPhool;
};

#endif // THREADWINDOW_H
